package com.huisou.scheduler;

import java.util.Date;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HTTPPostScheduler {
	private String						syncEnabled;
	private String[]					syncCores;
	private String						server;
	private String						port;
	private String						webapp;
	private String						command;
	private long						salerows;
	private long						buyrows;
	private long						comrows;
	private long						newsrows;
	private long						askrows;
	private long						perRows;
	private long						frirows;
	private int							startRow;
	private String						cores;
	private SolrDataImportProperties	p;
	
	private static final Logger			logger	= LoggerFactory.getLogger(HTTPPostScheduler.class);
	
	public HTTPPostScheduler() throws Exception {
		// load properties from global dataimport.properties
		p = new SolrDataImportProperties();
		reloadParams();
		fixParams();
		
		if (!syncEnabled.equals("1"))
			throw new Exception("Schedule disabled");
		
		logger.error("<索引更新进程> 当前有多个搜索实例准备更新索引: " + cores);
	}
	
	private void reloadParams() {
		p.loadProperties(true);
		syncEnabled = p.getProperty(SolrDataImportProperties.SYNC_ENABLED);
		cores = p.getProperty(SolrDataImportProperties.SYNC_CORES);
		server = p.getProperty(SolrDataImportProperties.SERVER);
		port = p.getProperty(SolrDataImportProperties.PORT);
		webapp = p.getProperty(SolrDataImportProperties.WEBAPP);
		command = p.getProperty(SolrDataImportProperties.COMMAND);
		salerows = Long.parseLong(p.getProperty(SolrDataImportProperties.SALEROWS));
		buyrows = Long.parseLong(p.getProperty(SolrDataImportProperties.BUYROWS));
		comrows = Long.parseLong(p.getProperty(SolrDataImportProperties.COMROWS));
		newsrows = Long.parseLong(p.getProperty(SolrDataImportProperties.NEWSROWS));
		askrows = Long.parseLong(p.getProperty(SolrDataImportProperties.ASKROWS));
		perRows = Long.parseLong(p.getProperty(SolrDataImportProperties.PERROWS));
		frirows = Long.parseLong(p.getProperty(SolrDataImportProperties.FRIROWS));
		startRow = Integer.parseInt(p.getProperty("startRow"));
		syncCores = cores != null ? cores.split(",") : null;
	}
	
	private void fixParams() {
		if (server == null || server.isEmpty())
			server = "localhost";
		if (port == null || port.isEmpty())
			port = "8080";
	}
	
	public void run() {
		logger.warn("<索引更新进程> 第一次执行");
		try {
			// check mandatory params
			if (server.isEmpty() || command == null || command.isEmpty()) {
				logger.warn("<索引更新进程> 准备读取参数");
				reloadParams();
				// single-core
			}
			else if (syncCores.length == 0 || (syncCores.length == 1 && syncCores[0].isEmpty())) {
				reloadParams();
			}
			else {
				for (String core : syncCores) {
					prepUrlSendHttpPost(core);
				}
			}
		}
		catch (Exception e) {
			logger.error("Failed to prepare for sendHttpPost", e);
			reloadParams();
		}
	}
	
	private void prepUrlSendHttpPost(String coreName) {
		logger.error("<索引更新进程>开始索引：" + coreName);
		String coreUrl = "http://" + server + "/" + coreName;
		if (!(port == null || "80".equals(port)))
			coreUrl = "http://" + server + ":" + port + "/" + coreName;
		if (!StringUtils.isBlank(webapp))
			coreUrl = "http://" + server + ":" + port + "/" + webapp + "/" + coreName;
		if (!StringUtils.isBlank(command))
			coreUrl += "/dataimport?command=" + command;
		int delayTime = 0;
		
		if ("full-import".equals(command)) {
			long totalRows = 10000;
			if ("sale".equals(coreName))
				totalRows = salerows;
			else if ("company".equals(coreName))
				totalRows = comrows;
			else if ("news".equals(coreName))
				totalRows = newsrows;
			else if ("ask".equals(coreName))
				totalRows = askrows;
			else if ("friends".equals(coreName))
				totalRows = frirows;
			
			int offset = 0;
			if (startRow > 0)
				offset = startRow;
			while (offset < totalRows) {
				String reqUrl = coreUrl + "&offset=" + offset + "&rows=" + perRows + "&synchronous=true";
				if (offset > 0)
					reqUrl += "&clean=false";
				if ("sale".equals(coreName))
					reqUrl += "&entity=product";
				sendHttpPost(reqUrl, coreName, delayTime);
				delayTime += 10;
				offset += perRows;
			}
			
			delayTime = 0;
			logger.error("共搜索{}数据{}行", coreName, offset);
			if ("sale".equals(coreName)) {
				totalRows = buyrows;
				offset = 0;
				while (offset < totalRows) {
					String reqUrl = coreUrl + "&offset=" + offset + "&rows=" + perRows + "&synchronous=true&clean=false&entity=buy";
					sendHttpPost(reqUrl, coreName, delayTime);
					offset += perRows;
					delayTime += 5;
				}
			}
			
		}
		else if ("delta-import".equals(command)) {
			coreUrl += "&clean=false&commit=true&synchronous=true";
			// 增量索引，每天晚上1点或2点进行optimize优化合并索引segment
			int hours = new Date().getHours();
			if (hours == 1 || hours == 2) {
				coreUrl += "&optimize=true";
			}
			sendHttpPost(coreUrl, coreName, delayTime);
		}
		logger.debug("<索引更新进程>完成索引：" + coreName);
	}
	
	private void sendHttpPost(String completeUrl, String coreName, int delayTime) {
		Date startTime = new Date();
		
		// prepare the core var
		String core = coreName == null ? "" : "[" + coreName + "] ";
		
		logger.error(core + "<索引更新进程> 开始索引 .............. " + completeUrl);
		HttpClient client = null;
		HttpMethod method = null;
		try {
			client = new HttpClient();
			method = new GetMethod(completeUrl);
			HttpClientParams hcp = new HttpClientParams();
			hcp.setSoTimeout(1000 * 60 * 20); // 10分钟请求延迟时间
			client.setParams(hcp);
			client.executeMethod(method);
			// Thread.sleep(1000*60+delayTime);
			String returnAD = method.getResponseBodyAsString();
			
			logger.error(core + "<索引更新进程> 请求返回信息\t\t\t" + returnAD);
			
			method.releaseConnection();// 释放连接
			
			Date endTime = new Date();
			long time = endTime.getTime() - startTime.getTime();
			// if(time>50)
			// Thread.sleep(time);
			logger.error(core + "<索引更新进程> 本次请求共用时 ................ " + time / 1000 + "秒");
		}
		catch (Exception e) {
			if (method != null && method.isRequestSent())
				method.releaseConnection();// 释放连接
			logger.error("索引请求执行失败", e);
		}
		finally {
			if (method != null && method.isRequestSent())
				method.releaseConnection();// 释放连接
		}
	}
}
